"""
    机器学习深度学习中，图像的识别和分类其实就是 让机器/模型通过大量的图像数据，提取特征，
    学习特征，总结规律，然后通过做分类做预测等。
    其中提取特征中，边缘信息是非常重要的。
    在图像中，像素信息变化比较大的区域就是边缘。
    边缘的提取可以使用差分法。
"""

import cv2
import numpy as np

img = cv2.imread('../images/shudu.png', cv2.IMREAD_GRAYSCALE)
# 缩小比例
img = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)

# kernel 卷积核 一个二维数组或矩阵
# 卷积核通常是一个奇数， 如3*3， 5*5， 7*7
# 卷积核的每个元素表示卷积核的权重,用于在卷积过程中与图像像素相乘。

# 定义一个提取垂直边缘提取的卷积核
# Sobel算子
# kernel_1 = np.array([[-1, 0, 1],
#                      [-2, 0, 2],
#                      [-1, -0, 1]])

# Sobel算子的加强版 Scharr算子
kernel_1 = np.array([[-3, 0, 3],
                     [-10, 0, 10],
                     [-3, -0, 3]])

img_filter2d = cv2.filter2D(img,
                            -1,
                            # 需要自己去定义卷积核
                            kernel=kernel_1,
                            )

# 转置矩阵，提取水平边缘
kernel_2 = kernel_1.T

img_filter2d_2 = cv2.filter2D(img,
                              -1,
                              # 需要自己去定义卷积核
                              kernel=kernel_2,
                              delta=30,  # 一个可选的附加值，它将被加到卷积结果上。这可以用于调整结果的亮度或对比度。
                              )

img_grad = cv2.addWeighted(img_filter2d, 0.5, img_filter2d_2, 0.5, 0)

img_stack = np.hstack([img, img_filter2d, img_filter2d_2, img_grad])
cv2.imshow("img_stack", img_stack)
cv2.waitKey(0)

"""
上面的那个卷积核其实都是sobel算子，kernel_1提取垂直边缘
kernel_2提取水平边缘，如果我想水平和垂直都提取呢？
1、计算水平梯度 Gx
2、再计算垂直梯度 Gy
3、然后 sqrt(Gx^2 + Gy^2) 或 cv2.addWeighted()
"""
